
#ifndef __ACTOR_H
#define __ACTOR_H

#include <apr_date.h>
#include "../aprtools/APRTable.h"
#include "SQLiteTransactor.h"

class BrokerMessage;
class ActorsDB;

/** A lazy-evaluating actor class in conjunction with the actors
 * database. */
class Actor
{
   public:
      /** Enumerater type for specifiying the actor class. */
      enum actortype { ACTOR_TYPE_UNSET         = (1 << 0),
                       ACTOR_TYPE_GENERIC       = (1 << 1),
                       ACTOR_TYPE_USER          = (1 << 2),
                       ACTOR_TYPE_COMPUTE       = (1 << 3),
                       ACTOR_TYPE_WORKINSTANCE  = (1 << 4),
                       ACTOR_TYPE_DATASTORE     = (1 << 5) };
      Actor(ActorsDB *inewadb);
      virtual ~Actor();

      void setName(const char *iname);
      void generateName();
      const char *getName();

      void setType(actortype itype);
      const actortype getType();

      void setTypeName(const char *istrtype);
      const char *getTypeName();
      
      int64_t getRemainingLife();
      
      SETGET_MACRO_AS_STRING_DECL(Actor, Parent, sqlite_actor_basic, "parent")
      SETGET_MACRO_AS_STRING_DECL(Actor, CreatedOn, sqlite_actor_basic, "createdon")
      SETGET_MACRO_AS_APRDATE_DECL(Actor, CreatedOn, sqlite_actor_basic, "createdon")
      SETGET_MACRO_AS_STRING_DECL(Actor, ValidFrom, sqlite_actor_basic, "validfrom")
      SETGET_MACRO_AS_APRDATE_DECL(Actor, ValidFrom, sqlite_actor_basic, "validfrom")
      SETGET_MACRO_AS_STRING_DECL(Actor, ExpiresOn, sqlite_actor_basic, "expireson")
      SETGET_MACRO_AS_APRDATE_DECL(Actor, ExpiresOn, sqlite_actor_basic, "expireson")
      SETGET_MACRO_AS_STRING_DECL(Actor, LastAccess, sqlite_actor_basic, "lastaccess")
      SETGET_MACRO_AS_APRDATE_DECL(Actor, LastAccess, sqlite_actor_basic, "lastaccess")
      ADDRMV_MACRO_AS_CHARFLAGS_DECL(Actor, ActorMark, sqlite_actor_basic, "actormark")
      SETGET_MACRO_AS_STRING_DECL(Actor, ExternalAlias, sqlite_actor_basic, "externalalias")
      SETGET_MACRO_AS_INT64_DECL(Actor, BlocksDone, sqlite_actor_basic, "blocksdone")
      SETGET_MACRO_AS_INT64_DECL(Actor, BlocksTotal, sqlite_actor_basic, "blockstotal")
      INCDEC_MACRO_AS_INT64_DECL(Actor, BlocksDone, sqlite_actor_basic, "blocksdone")
      INCDEC_MACRO_AS_INT64_DECL(Actor, BlocksTotal, sqlite_actor_basic, "blockstotal")

      SETGET_MACRO_AS_INT64_DECL(Actor, UserCredit, sqlite_actor_extended, "credit")
      SETGET_MACRO_AS_INT64_DECL(Actor, UserQuota, sqlite_actor_extended, "quota")

      SETGET_MACRO_AS_STRING_DECL(Actor, ComputeHost, sqlite_actor_extended, "host")
      SETGET_MACRO_AS_STRING_DECL(Actor, Capabilities, sqlite_actor_extended, "capabilities")

      SETGET_MACRO_AS_INT_DECL(Actor, WorkInstanceLocalID, sqlite_actor_extended, "instanceid")
      SETGET_MACRO_AS_STRING_DECL(Actor, WorkInstanceAccessCluster, sqlite_actor_extended, "assignedcluster")
      SETGET_MACRO_AS_STRING_DECL(Actor, WorkInstancePreferredCluster, sqlite_actor_extended, "preferredclusters")
      SETGET_MACRO_AS_STRING_DECL(Actor, WorkInstanceDataStore, sqlite_actor_extended, "inputdatastore")
      SETGET_MACRO_AS_STRING_DECL(Actor, WorkInstanceCompute, sqlite_actor_extended, "outputcompute")
      SETGET_MACRO_AS_INT_DECL(Actor, WorkInstanceResultBlocks, sqlite_actor_extended, "resultblocks")

      SETGET_MACRO_AS_INT_DECL(Actor, DataStoreBlocksHeld, sqlite_actor_extended, "blocksheld")
      SETGET_MACRO_AS_INT64_DECL(Actor, DataStoreBlockSize, sqlite_actor_extended, "blocksize")
      SETGET_MACRO_AS_STRING_DECL(Actor, DataStoreWorkHash, sqlite_actor_extended, "datahash")
      SETGET_MACRO_AS_INT_DECL(Actor, DataStoreLocalIDNos, sqlite_actor_extended, "instances")
      SETGET_MACRO_AS_STRING_DECL(Actor, DataStoreOrigin, sqlite_actor_extended, "origin")
      SETGET_MACRO_AS_STRING_DECL(Actor, DataStoreDecryptionKey, sqlite_actor_extended, "decryptionkey")

      SETGET_MACRO_AS_STRING_DECL(Actor, KeyDependencyKeyName, sqlite_actor_extended, "keyname")

      void precacheAll();
      bool commit();
      bool update();
      int updateBlocks(BrokerMessage &msgin);
      APRTable *getMetadata(apr_pool_t *mp);
      void setUncommitable();
   protected:
      /** Pointer to the actors database for database
       * transactions. */
      ActorsDB *newadb;
      
   private:
      /** Transactor for the basic (generic) actor fields. */
      SQLiteTransactor *sqlite_actor_basic;
      /** Transactor for the extended (type specific) actor fields. */ 
      SQLiteTransactor *sqlite_actor_extended;
      /** The type of actor of this actor held in this class. */
      actortype thistype;
      
      /** The names of the actors corresponding to the types. */
      static const char *actortypename[];
      void initNull();
      void init();
};

#endif
